package com.geline.mybatisplus.config;

import com.geline.mybatisplus.context.ExtractAfterThreadLocal;
import com.geline.mybatisplus.context.ExtractTableHelper;
import com.geline.mybatisplus.context.ExtractTableManager;
import com.geline.mybatisplus.context.ExtractTableThreadLocal;
import com.geline.mybatisplus.handler.*;
import com.geline.mybatisplus.handler.impl.DefaultForeignKeyHandler;
import com.geline.mybatisplus.interceptor.MybatisInnerAfterInterceptor;
import com.geline.mybatisplus.interceptor.inner.ExtractAfterInterceptor;
import com.geline.mybatisplus.interceptor.inner.ExtractTableInterceptor;
import com.geline.mybatisplus.service.DbService;
import com.geline.mybatisplus.service.EasyExtractHandler;
import com.geline.mybatisplus.service.EasyExtractService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration
@Slf4j
public class MybatisExtractConfiguration implements ApplicationRunner {

    @Bean
    @ConditionalOnMissingBean
    public DbService initCrudTableService(){
        return new DbService();
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractTableThreadLocal initExtractTableThreadLocal(){
        return new ExtractTableThreadLocal();
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractAfterThreadLocal initExtractAfterThreadLocal(){
        return new ExtractAfterThreadLocal();
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractTableHandler initExtractTableHandler(JdbcTemplate jdbcTemplate){
        return new ExtractTableHandler(jdbcTemplate);
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractStatusHandler initExtractStatusHandler(){
        return new ExtractStatusHandler();
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractStatus3Handler initExtractStatus3Handler(JdbcTemplate jdbcTemplate){
        return new ExtractStatus3Handler(jdbcTemplate);
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractValueHandler initExtractValueHandler(){
        return new ExtractValueHandler();
    }

    @Bean
    @ConditionalOnMissingBean
    public ForeignKeyHandler initForeignKeyHandler(JdbcTemplate jdbcTemplate){
        return new DefaultForeignKeyHandler(jdbcTemplate);
    }

    @Bean
    @ConditionalOnMissingBean
    public ExtractTableManager initExtractTableManager(ExtractTableThreadLocal threadLocal, ForeignKeyHandler foreignKeyHandler){
        return new ExtractTableManager(threadLocal, foreignKeyHandler);
    }

    @Bean
    @ConditionalOnMissingBean
    public MybatisInnerAfterInterceptor mybatisInnerAfterInterceptor(ExtractTableManager extractTableManager, ExtractAfterThreadLocal afterThreadLocal, ForeignKeyHandler foreignKeyHandler) {
        MybatisInnerAfterInterceptor interceptor = new MybatisInnerAfterInterceptor();
        //处理 @ExtractAfter
        interceptor.addInnerInterceptor(new ExtractAfterInterceptor(afterThreadLocal));
        //子表更新后同步更新主表 @ExtractTable @ExtractCount @ExtractSum @ExtractKey @ExtractStatus
        interceptor.addInnerInterceptor(new ExtractTableInterceptor(extractTableManager, foreignKeyHandler));
        return interceptor;
    }

    @Bean
    @ConditionalOnMissingBean
    public EasyExtractHandler initEasyExtractHandler(ExtractTableHandler extractTableHandler, ExtractStatusHandler extractStatusHandler,
                                                     ExtractStatus3Handler extractStatus3Handler, ExtractValueHandler extractValueHandler){
        return new EasyExtractHandler(extractTableHandler, extractStatusHandler, extractStatus3Handler, extractValueHandler);
    }

    @Bean
    @ConditionalOnMissingBean
    public EasyExtractService initEasyExtractService(ExtractAfterThreadLocal afterThreadLocal, ExtractTableThreadLocal tableThreadLocal, EasyExtractHandler easyExtractHandler){
        return new EasyExtractService(afterThreadLocal, tableThreadLocal, easyExtractHandler);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        ExtractTableHelper.init();
        log.info(">>>>>>>>>>>>MybatisExtractConfiguration>>>>>>>>over>>>>>>>>>>>");
    }
}
